Skip to content

fix(desktop): reorder repo tabs via pointer events (mouse, touch, pen) + keyboard a11y#121

Merged
devlint merged 5 commits into
mainfrom
fix/tab-reorder-pointer-drag
Jul 10, 2026
Merged

fix(desktop): reorder repo tabs via pointer events (mouse, touch, pen) + keyboard a11y#121
devlint merged 5 commits into
mainfrom
fix/tab-reorder-pointer-drag

Conversation

@t1gu1

@t1gu1 t1gu1 commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

The native HTML5 drag-and-drop is unreliable in the WebKit webviews that host the Tauri app, where dragstart often fails to fire. This change drives tab reordering with pointer events instead (mouse, touch and pen in one code path), adds a keyboard equivalent for accessibility, and improves the visibility of inactive repo tabs.

Changes

  • Replace native HTML5 drag-and-drop with pointer-event-driven tab reordering in RepoTabStrip.vue
  • Add a subtle outline to inactive repo tabs so they remain distinguishable
  • Increase the opacity of tab affordances (caret, close button) so they stay perceptible without hover

Accessibility & cross-input follow-ups

  • Migrated mouse events → Pointer Events (setPointerCapture, feature-detected) — touch/pen drag now works, not just mouse.
  • Added Ctrl/Cmd+Shift+ArrowLeft/Right keyboard reordering with an aria-live announcement — screen reader / keyboard-only users previously had no way to reorder tabs at all. (Shift is required alongside Ctrl/Cmd: a bare Ctrl+Arrow is macOS's default Mission Control "switch Space" shortcut, intercepted by the OS before any app — browsers included — ever sees the keydown.)
  • Re-snapshot tab centers on window resize mid-drag, not just on strip scroll.
  • Fixed a double-counting bug in the mid-drag re-snapshot logic (the dragged tab's live translateX was being measured back into the snapshot, then added a second time) that would otherwise have shipped a new drag-offset bug on scroll/resize.
  • Fixed several correctness issues found in code review: an asymmetric hit-test that could trigger an accidental reorder from a few pixels of hand wobble, drags committing on any mouse button or with no way to cancel, a stale didDrag flag that could swallow a keyboard tab activation, and a click-to-focus regression from an unconditional preventDefault().

Test plan

  • Drag a repo tab to a new position and confirm the order updates
  • Verify reordering works inside the Tauri desktop app (WebKit webview)
  • Confirm active and inactive tabs are visually distinguishable
  • Check caret and close affordances are visible without hovering
  • Reorder a tab via keyboard (focus a tab, Ctrl/Cmd+Shift+ArrowLeft/Right) and confirm both the order update and the screen-reader announcement
  • Confirm touch/pen drag reordering works on a touch-capable device, if available
  • Resize the window mid-drag and confirm the drop still lands on the intended tab

How it looks

Before

image

Now

image

Guillaume Huard Hughes added 2 commits July 8, 2026 13:04
Le drag-and-drop HTML5 natif est peu fiable dans les webviews WebKit
qui font tourner l'app Tauri : dragstart ne se déclenche souvent pas.
On pilote le réordonnancement avec des événements souris à la place.

🪄 Commit via GitWand
Ajoute un contour discret aux onglets inactifs et augmente l'opacité des
affordances (caret, fermeture) pour qu'elles restent perceptibles sans survol.

🪄 Commit via GitWand
@t1gu1 t1gu1 requested a review from devlint July 8, 2026 17:06
Laurent Guitton added 2 commits July 9, 2026 10:53
Addresses correctness defects in the RepoTabStrip.vue pointer-drag
rewrite found in PR #121's review:

- Hit-test now compares the dragged tab's own shifted center (offset
  from its drag-start position) against the other tabs' centers,
  instead of the raw cursor position — a press near a tab's edge no
  longer overshoots into a reorder from a few pixels of hand wobble.
- Only the left mouse button can end a drag; a right/middle-click
  released mid-drag (e.g. after middle-click closed another tab) is
  ignored instead of committing a stale reorder.
- Releasing well above/below the strip, pressing Escape, or losing the
  mouseup to a window blur (alt-tab, native dialog) cancels the drag
  instead of always committing wherever the cursor lands.
- Tab centers are re-snapshotted on strip scroll, and a tab
  opening/closing mid-drag now aborts the drag instead of committing
  against a stale position/index snapshot.
- `didDrag` resets on a deferred tick rather than only via the
  trailing click, so it can't get stuck and swallow the next keyboard
  tab activation when the mouseup lands off the dragged tab.
- Dropped the unconditional `preventDefault()` on tab mousedown, which
  was suppressing click-to-focus on the tablist (text selection is
  already blocked by `user-select: none` in CSS).
- Removed the dead `.repo-tab__caret` branch from the drag-start guard
  (the caret already stops propagation on its own mousedown).

Adds regression coverage for the wobble/reorder, wrong-button, and
cancel-outside/blur cases.
disabled
Extends the tab-reorder fix per code-review follow-ups:

- Migrate mouse events to Pointer Events (setPointerCapture, feature-
  detected with a try/catch fallback) so drag-to-reorder works with
  touch and pen input, not just a mouse. `touch-action: none` on the
  tab claims the horizontal pan gesture so the strip's native
  overflow-x scroll can't win the race and hijack a touch drag
  mid-way; `pointercancel` cancels the drag if it does anyway.
- Add Ctrl/Cmd+ArrowLeft/Right keyboard reordering with an aria-live
  announcement (`role="status"`) — the pointer/touch drag had no
  keyboard equivalent, leaving reordering unreachable without a mouse,
  trackpad or touchscreen.
- Re-snapshot tab centers on window resize mid-drag too, not just on
  strip scroll — a resize shifts every tab's viewport position the
  same way a scroll does.
- Fix a double-counting bug in that re-snapshot logic: re-measuring
  the dragged tab's rect mid-drag picks up its live translateX, which
  then got added to the drag offset a second time in the hit-test,
  overshooting the drop by however far the tab had already moved.

New locale key `header.tabStripReorderAnnounce` added to all 5
locales for the keyboard-reorder announcement.
disabled
@devlint devlint changed the title fix(desktop): reorder repo tabs via pointer events fix(desktop): reorder repo tabs via pointer events (mouse, touch, pen) + keyboard a11y Jul 9, 2026
Bare Ctrl+ArrowLeft/Right collides with macOS's default Mission
Control "switch Space" shortcut, which the OS intercepts before the
keydown ever reaches any app — a browser included, so this isn't
Tauri-specific. Cmd+Arrow isn't bound by default, but third-party
window-manager utilities and user remaps commonly claim bare
Ctrl/Cmd+Arrow too.

Require Shift alongside Ctrl/Cmd (Ctrl/Cmd+Shift+ArrowLeft/Right) to
stay clear of every OS-level and third-party shortcut we know of for
this combo, the same reasoning VS Code's editor-move commands use a
Shift-modified combo rather than a bare arrow. Updates the
aria-keyshortcuts hint and adds a regression test confirming a bare
Ctrl+Arrow (no Shift) no longer triggers a reorder.
disabled
@devlint devlint merged commit f726662 into main Jul 10, 2026
4 checks passed
@devlint devlint deleted the fix/tab-reorder-pointer-drag branch July 10, 2026 14:07
devlint pushed a commit that referenced this pull request Jul 10, 2026
Combines the previously separate v3.5 (secrets scanner) and v3.6 (PR
Review 2.0) roadmap items into a single release, plus PR badge
background prefetch/cache, dock PR count, repo-tab reorder a11y fix,
and the File Explorer Save button move already merged to main.

- CHANGELOG.md: renamed Unreleased to 3.5.0, folded in the three extra
  merged PRs (#125, #122, #121)
- ROADMAP.md: moved v3.5/v3.6 to Shipped as one entry, renumbered every
  future planned version down by one to close the gap
- website/changelog.md: narrative mirror entry for v3.5.0
- New blog post (PR Review 2.0 + secrets scanner), wired into the blog
  index, sidebar, and homepage teaser; homepage hero-announce banner
  updated in all 5 locales
- New "Support GitWand" sponsor section on the homepage, all 5 locales
- Fixed a stale usePrPanel.test.ts mock missing detectClaudeCli
  (broke after PR Review 2.0 wired useReviewIntelligence into the
  usePrPanel import chain)
- Version bump via ./scripts/bump-version.sh 3.5.0

disabled
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants